package com.qumitech.visualnovel.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qumitech.visualnovel.component.util.DateUtil;
import com.qumitech.visualnovel.component.util.TimeUtils;
import com.qumitech.visualnovel.datasource.console.GiftStatisticDOMapper;
import com.qumitech.visualnovel.datasource.console.OutputCommissionStatisticsMapper;
import com.qumitech.visualnovel.datasource.console.ProfitStatisticDOMapper;
import com.qumitech.visualnovel.datasource.console.StockStatisticsMapper;
import com.qumitech.visualnovel.datasource.console.OutputConsumptionDetailMapper;
import com.qumitech.visualnovel.datasource.console.DailyRechargeDataDOMapper;
import com.qumitech.visualnovel.model.dao.console.*;
import com.qumitech.visualnovel.pubdef.dto.economic.*;

import com.qumitech.visualnovel.service.EconomicStatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class EconomicStatisticsServiceImpl implements EconomicStatisticsService {

    @Autowired
    OutputCommissionStatisticsMapper outputMapper;

    @Autowired
    StockStatisticsMapper stockMapper;

    @Autowired
    ProfitStatisticDOMapper profitMapper;

    @Autowired
    GiftStatisticDOMapper giftMapper;

    @Autowired
    DateUtil dateUtil;

    @Autowired
    OutputConsumptionDetailMapper outputConsumptionDetailMapper;

    @Autowired
    DailyRechargeDataDOMapper dailyRechargeDataDOMapper;

    private JSONObject getSeriesItem(String matchTypeName, Map<String,Long> tempMap) {
        JSONObject seriesItem = new JSONObject();
        seriesItem.put("name", matchTypeName);
        seriesItem.put("type", "line");
        JSONArray seriesItemDataList = new JSONArray();
        for(String key : tempMap.keySet()) {
            seriesItemDataList.add(tempMap.get(key));
        }

        seriesItem.put("data", seriesItemDataList);
        JSONObject areaStyle = JSONObject.parseObject("{normal: {}}");
        seriesItem.put("areaStyle", areaStyle);
        return seriesItem;
    }

    private JSONObject getLine(Map<String,Long> tempMap, String startTime, String endTime, String matchTypeName) {
        JSONArray xAxis = new JSONArray();

        JSONObject legend = new JSONObject();
        JSONArray legendList = new JSONArray();
        legendList.add(tempMap);
        legend.put("data",legendList);

        List<String> dateList= dateUtil.getnDayList(startTime, endTime);
        JSONObject xAxisData = new JSONObject();
        xAxisData.put("data", JSONArray.parseArray(JSON.toJSONString(dateList)));
        xAxis.add(xAxisData);

        JSONArray series = new JSONArray();
        series.add(getSeriesItem(matchTypeName, tempMap));

        JSONObject yAxis = new JSONObject();
        yAxis.put("type", "value");

        JSONObject resObj = new JSONObject();
        resObj.put("xAxis", xAxis);
        resObj.put("series", series);
        resObj.put("yAxis", yAxis);
        resObj.put("legend", legend);
        return resObj;
    }

    @Override
    public JSONObject getOutputCommissionStatisticsLine(String channel, String version, String propId,
                                                        String startTime, String endTime) {

        JSONObject legend = new JSONObject();
        JSONArray legendList = new JSONArray();
        legendList.add("产出");
        legendList.add("消耗");
        legend.put("data",legendList);

        JSONArray xAxis = new JSONArray();
        List<String> dateList= dateUtil.getnDayList(startTime, endTime);
        JSONObject xAxisData = new JSONObject();
        xAxisData.put("data", JSONArray.parseArray(JSON.toJSONString(dateList)));
        xAxis.add(xAxisData);
        JSONArray series = new JSONArray();
        Map<String,Long> tempOutputMap = dateUtil.GetNDaysMap(startTime,endTime);
        Map<String,Long> tempCommissionMap = dateUtil.GetNDaysMap(startTime,endTime);
        List <OutputCommissionStatistics> outputCommissionStatisticsList =
                outputMapper.getLine(channel,version,propId,null,startTime, endTime);
        for (OutputCommissionStatistics outputCommissionStatistics: outputCommissionStatisticsList)
        {
            tempOutputMap.put(dateUtil.dateToStr(outputCommissionStatistics.getTargetDate()),
                    outputCommissionStatistics.getOutput());
            tempCommissionMap.put(dateUtil.dateToStr(outputCommissionStatistics.getTargetDate()),
                    outputCommissionStatistics.getCommission());
        }
        series.add(getSeriesItem("产出", tempOutputMap));
        series.add(getSeriesItem("消耗", tempCommissionMap));
        JSONObject resObj = new JSONObject();
        resObj.put("legend", legend);
        resObj.put("xAxis", xAxis);
        resObj.put("series", series);
        return resObj;
    }

    @Override
    public List<OutputCommissionStatistics> getOutputCommissionStatisticsList(String channel, String version,
                                                                              String propId, String startTime,
                                                                              String endTime, int offset, int limit,
                                                                              String orderType, String orderBy) {
        List <OutputCommissionStatistics> outputCommissionStatisticsList = outputMapper.getList(
                channel,version,propId,null,startTime,endTime,offset,limit,orderType,orderBy);
        for(OutputCommissionStatistics outputCommissionStatistics: outputCommissionStatisticsList)
        {
            if(channel == null) {
                outputCommissionStatistics.setAppChannel("全部");
            }
            else {
                outputCommissionStatistics.setAppChannel(channel);
            }
            if(version == null) {
                outputCommissionStatistics.setAppVersion("全部");
            }
            else {
                outputCommissionStatistics.setAppVersion(version);
            }
            if(propId == null) {
                outputCommissionStatistics.setPropId("全部");
            }
            else {
                outputCommissionStatistics.setPropId(propId);
            }

        }
        return outputCommissionStatisticsList;
    }

    @Override
    public int getOutputCommissionStatisticsCount(String channel, String version, String propId,
                                                  String startTime, String endTime) {
        return outputMapper.getCount(channel,version,propId,null, startTime,endTime);
    }

    @Override
    public OutputCommissionStatistics getOutputCommissionStatisticsSum(String channel, String version, String propId,
                                                                       String startTime, String endTime) {
        return outputMapper.getSum(channel, version, propId, null, startTime, endTime);
    }

    @Override
    public JSONObject getOutputStatisticsLine(String channel, String version, String propId, Integer changeId,
                                              String startTime, String endTime) {
        List <OutputCommissionStatistics> outputCommissionStatisticsList = outputMapper.getLine(
                channel,version,propId,changeId, startTime, endTime);
        Map<String,Long> tempMap = dateUtil.GetNDaysMap(startTime,endTime);
        for (OutputCommissionStatistics outputCommissionStatistics: outputCommissionStatisticsList)
        {
            tempMap.put(dateUtil.dateToStr(outputCommissionStatistics.getTargetDate()),
                    outputCommissionStatistics.getOutput());
        }
        return getLine(tempMap, startTime, endTime, "产出曲线");
    }

    @Override
    public List<OutputCommissionStatistics> getOutputStatisticsList(String channel, String version, String propId,
                                                                    Integer changeId, String startTime, String endTime,
                                                                    int offset, int limit, String orderType,
                                                                    String orderBy) {
        List <OutputCommissionStatistics> outputCommissionStatisticsList = outputMapper.getList(
                channel,version,propId,changeId,startTime,endTime,offset,limit,orderType,orderBy);
        for(OutputCommissionStatistics outputCommissionStatistics: outputCommissionStatisticsList)
        {
            if(channel == null) {
                outputCommissionStatistics.setAppChannel("全部");
            }
            else {
                outputCommissionStatistics.setAppChannel(channel);
            }
            if(version == null) {
                outputCommissionStatistics.setAppVersion("全部");
            }
            else {
                outputCommissionStatistics.setAppVersion(version);
            }
            if(propId == null) {
                outputCommissionStatistics.setPropId("全部");
            }
            else {
                outputCommissionStatistics.setPropId(propId);
            }
            if(changeId == null)
            {
                outputCommissionStatistics.setChangeId(0);
            }
            else
            {
                outputCommissionStatistics.setChangeId(changeId);
            }
        }
        return outputCommissionStatisticsList;
    }

    @Override
    public int getOutputStatisticsCount(String channel, String version, String propId, Integer changeId,
                                        String startTime, String endTime) {
        return outputMapper.getCount(channel,version,propId,changeId,startTime,endTime);
    }

    @Override
    public JSONObject getCommissionStatisticsLine(String channel, String version, String propId, Integer changeId,
                                                  String startTime, String endTime) {
        List <OutputCommissionStatistics> outputCommissionStatisticsList = outputMapper.getLine(
                channel,version,propId,changeId, startTime, endTime);
        Map<String,Long> tempMap = dateUtil.GetNDaysMap(startTime,endTime);
        for (OutputCommissionStatistics outputCommissionStatistics: outputCommissionStatisticsList)
        {
            tempMap.put(dateUtil.dateToStr(outputCommissionStatistics.getTargetDate()),
                    outputCommissionStatistics.getCommission());
        }
        return getLine(tempMap, startTime, endTime, "消耗曲线");
    }

    @Override
    public List<OutputCommissionStatistics> getCommissionStatisticsList(String channel, String version, String propId,
                                                                        Integer changeId, String startTime,
                                                                        String endTime, int offset, int limit,
                                                                        String orderType, String orderBy) {
        return getOutputStatisticsList(channel, version, propId, changeId, startTime, endTime,
                offset, limit, orderType, orderBy);
    }

    @Override
    public int getCommissionStatisticsCount(String channel, String version, String propId, Integer changeId,
                                            String startTime, String endTime) {
        return outputMapper.getCount(channel,version,propId,changeId,startTime,endTime);
    }

    private List<String> getSplitChannel(String channel) {
        String appChannel = null;
        String subChannel = null;
        String splitStr = ":";
        if (channel != null && !channel.contains(splitStr)) {
            appChannel = channel;
        }
        if (channel != null && channel.contains(splitStr)) {
            String[] channels = channel.split(splitStr);
            appChannel = channels[0];
            subChannel = channels[1];
        }

        List<String> channelList = new ArrayList<>(16);
        channelList.add(appChannel);
        channelList.add(subChannel);
        return channelList;
    }

    @Override
    public JSONObject getStockStatisticsLine(String channel, String propId, String startTime, String endTime) {
        List<String> channels = getSplitChannel(channel);
        List <StockStatistics> stockStatisticsList = stockMapper.getLine(channels.get(0), channels.get(1),
                propId, startTime, endTime);
        Map<String,Long> tempMap = dateUtil.GetNDaysMap(startTime,endTime);
        for (StockStatistics stockStatistics: stockStatisticsList) {
            tempMap.put(dateUtil.dateToStr(stockStatistics.getTargetDate()), Long.valueOf(stockStatistics.getData()));
        }
        return getLine(tempMap, startTime, endTime, "存量曲线");
    }

    @Override
    public StockStatistics getStockStatisticsSum(String channel, String propId, String startTime, String endTime) {
        List<String> channels = getSplitChannel(channel);
        return stockMapper.getSum(channels.get(0), channels.get(1), propId, startTime,endTime);
    }

    @Override
    public List<StockStatistics> getStockStatisticsList(String channel, String propId, String startTime, String endTime,
                                                        int offset, int limit, String orderType, String orderBy) {
        List<String> channels = getSplitChannel(channel);
        List <StockStatistics> stockStatisticsList = stockMapper.getList(channels.get(0), channels.get(1),
                propId, startTime, endTime, offset, limit, orderType, orderBy);
        for(StockStatistics stockStatistics: stockStatisticsList) {
            if(propId == null) {
                stockStatistics.setPropId("全部");
            }
            else {
                stockStatistics.setPropId(propId);
            }
        }
        return stockStatisticsList;
    }

    @Override
    public int getStockStatisticsCount(String channel, String propId, String startTime, String endTime) {
        List<String> channels = getSplitChannel(channel);
        return stockMapper.getCount(channels.get(0), channels.get(1), propId, startTime, endTime);
    }

    @Override
    public List<ProfitStatisticDO> profitStatisticList(String channel, String startTime, String endTime,
                                                       int offset, int limit, String orderType, String orderBy) {
        return profitMapper.profitStatisticList(channel, startTime, endTime, offset, limit, orderType, orderBy);
    }

    @Override
    public Integer countProfitStatistic(String channel, String startTime, String endTime) {
        return profitMapper.countProfitStatistic(channel, startTime, endTime);
    }

    @Override
    public ProfitStatisticDO sumProfitStatistic(String channel, String startTime, String endTime) {
        return profitMapper.sumProfitStatistic(channel, startTime, endTime);
    }

    @Override
    public List<GiftStatisticDO> giftStatisticList(String channel, String startTime, String endTime,
                                                   int offset, int limit, String orderType, String orderBy) {
        return giftMapper.giftStatisticList(channel, startTime, endTime, offset, limit, orderType, orderBy);
    }

    @Override
    public Integer countGiftStatistic(String channel, String startTime, String endTime) {
        return giftMapper.countGiftStatistic(channel, startTime, endTime);
    }

    @Override
    public GiftStatisticDO sumGiftStatistic(String channel, String startTime, String endTime) {
        return giftMapper.sumGiftStatistic(channel, startTime, endTime);
    }

    @Override
    public JSONObject getGiftStatisticLine(String channel, String startTime, String endTime) {
        List <GiftStatisticDO> giftStatisticDOList = giftMapper.getLine(channel, startTime, endTime);
        Map<String,Long> tempMap = dateUtil.GetNDaysMap(startTime,endTime);
        for (GiftStatisticDO giftStatisticDO: giftStatisticDOList)
        {
            tempMap.put(dateUtil.dateToStr(giftStatisticDO.getTargetDate()), giftStatisticDO.getStockValue());
        }
        return getLine(tempMap, startTime, endTime, "礼物存量价值曲线");
    }

    @Override
    public JSONArray diamondOutputDetail(String channel, String startTime, String endTime) {
        Integer []changeId =  {1, 5, 7, 8, 9, 11, 12, 13, 118};
        List<Integer> changeIdList = Arrays.asList(changeId);
        JSONArray diamondOutputs = new JSONArray();
        List<OutputCommissionStatistics> outputCommissionStatisticsList =
                outputMapper.outputDetail("diamond", changeIdList, channel, startTime, endTime);

        boolean isFirst = true;
        DiamondOutputDTO diamondOutputDTO = new DiamondOutputDTO();
        Date lastTargetDate=null;
        for(OutputCommissionStatistics commissionStatistics: outputCommissionStatisticsList){
            if (!commissionStatistics.getTargetDate().equals(lastTargetDate) && !isFirst){
                diamondOutputs.add(diamondOutputDTO);
                diamondOutputDTO = new DiamondOutputDTO();
            }
            switch (commissionStatistics.getChangeId()){
                case 1:
                    diamondOutputDTO.setRechargePurchase(commissionStatistics.getOutput());
                    break;
                case 11:
                    diamondOutputDTO.setProfitExchange(commissionStatistics.getOutput());
                    break;
                case 9:
                    diamondOutputDTO.setCustomerSupplement(commissionStatistics.getOutput());
                    break;
                case 7:
                    diamondOutputDTO.setAnsweringQuestionReward(commissionStatistics.getOutput());
                    break;
                case 8:
                    diamondOutputDTO.setGuessSongReward(commissionStatistics.getOutput());
                    break;
                case 5:
                    diamondOutputDTO.setActivitySend(commissionStatistics.getOutput());
                    break;
                case 12:
                    diamondOutputDTO.setVoiceRoomRebate(commissionStatistics.getOutput());
                    break;
                case 13:
                    diamondOutputDTO.setAccompanyOrderRefund(commissionStatistics.getOutput());
                    break;
                case 118:
                    diamondOutputDTO.setNobleRefund(commissionStatistics.getOutput());
                    break;
                default:
                    break;
            }
            lastTargetDate = commissionStatistics.getTargetDate();
            diamondOutputDTO.setTargetDate(lastTargetDate);
            isFirst = false;
        }
        if (!isFirst) {
            diamondOutputs.add(diamondOutputDTO);
        }
        return diamondOutputs;
    }

    @Override
    public JSONObject diamondOutputPercent(String channel, String startTime, String endTime) {
        JSONArray diamondOutputs = diamondOutputDetail(channel, startTime, endTime);
        List<DiamondOutputDTO> diamondOutputDTOList = JSONObject.parseArray(diamondOutputs.toJSONString(),
                DiamondOutputDTO.class);
        List<String> dateList= dateUtil.getnDayList(startTime, endTime);
        Long[][] data = new Long[9][dateList.size()];
        String []name = {"充值购买", "贵族返还", "收益兑换钻石", "客服补单", "答题段位奖励", "猜歌词段位奖励", "一元上车", "返点兑换钻石",
                         "陪玩订单退款"};
        HashMap<String, DiamondOutputDTO> dataMap = new HashMap<>(16);
        for(DiamondOutputDTO diamondOutputDTO: diamondOutputDTOList){
            dataMap.put(TimeUtils.getTime(diamondOutputDTO.getTargetDate().getTime(),
                    TimeUtils.DATE_FORMAT_DATE_D), diamondOutputDTO);
        }
        for(int i=0;i<dateList.size(); i++){
            DiamondOutputDTO diamondOutputDTO = dataMap.get(dateList.get(i));
            if (diamondOutputDTO != null) {
                data[0][i] = diamondOutputDTO.getRechargePurchase();
                data[1][i] = diamondOutputDTO.getNobleRefund();
                data[2][i] = diamondOutputDTO.getProfitExchange();
                data[3][i] = diamondOutputDTO.getCustomerSupplement();
                data[4][i] = diamondOutputDTO.getAnsweringQuestionReward();
                data[5][i] = diamondOutputDTO.getGuessSongReward();
                data[6][i] = diamondOutputDTO.getActivitySend();
                data[7][i] = diamondOutputDTO.getVoiceRoomRebate();
                data[8][i] = diamondOutputDTO.getAccompanyOrderRefund();
            }
            else{
                for(int j = 0; j < name.length; j++)
                {
                    data[j][i] = 0L;
                }
            }
        }

        return generateResponse(name, data, dateList);
    }

    @Override
    public JSONArray coinOutputDetail(String channel, String startTime, String endTime) {
        Integer []changeId =  {2, 3, 4, 6, 7, 8, 9};
        List<Integer> changeIdList = Arrays.asList(changeId);
        JSONArray coinOutputs = new JSONArray();
        List<OutputCommissionStatistics> outputCommissionStatisticsList =
                outputMapper.outputDetail("coins", changeIdList, channel, startTime, endTime);

        boolean isFirst = true;
        CoinOutputDTO coinOutput = new CoinOutputDTO();
        Date lastTargetDate = null;
        for(OutputCommissionStatistics commissionStatistics: outputCommissionStatisticsList){
            if (!commissionStatistics.getTargetDate().equals(lastTargetDate) && !isFirst){
                coinOutputs.add(coinOutput);
                coinOutput = new CoinOutputDTO();
            }
            switch (commissionStatistics.getChangeId()){
                case 1:
                    coinOutput.setRechargePurchase(commissionStatistics.getOutput());
                    break;
                case 2:
                    coinOutput.setTaskReward(commissionStatistics.getOutput());
                    break;
                case 3:
                    coinOutput.setSignReward(commissionStatistics.getOutput());
                    break;
                case 4:
                    coinOutput.setRegisterSend(commissionStatistics.getOutput());
                    break;
                case 6:
                    coinOutput.setDiamondExchangeCoin(commissionStatistics.getOutput());
                    break;
                case 7:
                    coinOutput.setAnsweringQuestionReward(commissionStatistics.getOutput());
                    break;
                case 8:
                    coinOutput.setGuessSongReward(commissionStatistics.getOutput());
                    break;
                case 9:
                    coinOutput.setCustomerSupplement(commissionStatistics.getOutput());
                    break;
                default:
                    break;
            }
            lastTargetDate = commissionStatistics.getTargetDate();
            coinOutput.setTargetDate(lastTargetDate);
            isFirst = false;
        }

        if (!isFirst) {
            coinOutputs.add(coinOutput);
        }

        return coinOutputs;
    }

    @Override
    public JSONObject coinOutputPercent(String channel, String startTime, String endTime) {
        JSONArray coinOutputs = coinOutputDetail(channel, startTime, endTime);
        List<CoinOutputDTO> coinOutputDTOList = JSONObject.parseArray(coinOutputs.toJSONString(),
                CoinOutputDTO.class);
        List<String> dateList= dateUtil.getnDayList(startTime, endTime);
        Long[][] data = new Long[8][dateList.size()];
        String[] name = {"充值购买", "任务奖励", "签到奖励", "注册赠送", "钻石兑换金豆", "答题段位奖励", "猜歌词段位奖励",
                         "客服补单"};
        HashMap<String, CoinOutputDTO> dataMap = new HashMap<>(16);
        for(CoinOutputDTO coin: coinOutputDTOList) {
            dataMap.put(TimeUtils.getTime(coin.getTargetDate().getTime(), TimeUtils.DATE_FORMAT_DATE_D), coin);
        }

        for(int i = 0; i < dateList.size(); i++) {
            CoinOutputDTO coinOutput = dataMap.get(dateList.get(i));
            if (coinOutput != null) {
                data[0][i] = coinOutput.getRechargePurchase();
                data[1][i] = coinOutput.getTaskReward();
                data[2][i] = coinOutput.getSignReward();
                data[3][i] = coinOutput.getRegisterSend();
                data[4][i] = coinOutput.getDiamondExchangeCoin();
                data[5][i] = coinOutput.getAnsweringQuestionReward();
                data[6][i] = coinOutput.getGuessSongReward();
                data[7][i] = coinOutput.getCustomerSupplement();
            } else {
                for(int j = 0; j < name.length; j++)
                {
                    data[j][i] = 0L;
                }
            }
        }

        return generateResponse(name, data, dateList);
    }

    @Override
    public JSONArray hiCoinOutputDetail(String channel, String startTime, String endTime) {
        Integer []changeId =  {1, 5, 9, 13, 15};
        List<Integer> changeIdList = Arrays.asList(changeId);
        JSONArray hiCoinOutputs = new JSONArray();
        List<OutputCommissionStatistics> outputCommissionStatisticsList
                = outputMapper.outputDetail("hicoin", changeIdList, channel, startTime, endTime);
        boolean isFirst = true;
        HiCoinOutputDTO hiCoinOutput = new HiCoinOutputDTO();
        Date lastTargetDate=null;
        for(OutputCommissionStatistics commissionStatistics: outputCommissionStatisticsList){
            if (!commissionStatistics.getTargetDate().equals(lastTargetDate) && !isFirst){
                hiCoinOutputs.add(hiCoinOutput);
                hiCoinOutput = new HiCoinOutputDTO();
            }
            switch (commissionStatistics.getChangeId()){
                case 1:
                    hiCoinOutput.setRechargePurchase(commissionStatistics.getOutput());
                    break;
                case 5:
                    hiCoinOutput.setActivityFund(commissionStatistics.getOutput());
                    break;
                case 9:
                    hiCoinOutput.setConsoleRelease(commissionStatistics.getOutput());
                    break;
                case 13:
                    hiCoinOutput.setOrderRefund(commissionStatistics.getOutput());
                    break;
                case 15:
                    hiCoinOutput.setOrderWalletPay(commissionStatistics.getOutput());
                default:
                    break;
            }
            lastTargetDate = commissionStatistics.getTargetDate();
            hiCoinOutput.setTargetDate(lastTargetDate);
            isFirst = false;
        }

        if (!isFirst) {
            hiCoinOutputs.add(hiCoinOutput);
        }

        return hiCoinOutputs;
    }

    @Override
    public JSONObject hiCoinOutputPercent(String channel, String startTime, String endTime) {
        JSONArray hiCoinOutputs = hiCoinOutputDetail(channel, startTime, endTime);
        List<HiCoinOutputDTO> hiCoinOutputDTOList = JSONObject.parseArray(
                hiCoinOutputs.toJSONString(), HiCoinOutputDTO.class);
        List<String> dateList= dateUtil.getnDayList(startTime, endTime);
        Long[][] data = new Long[5][dateList.size()];
        String []name = {"充值购买", "活动发放", "控制台发放", "陪玩订单退款", "嗨币收益兑换"};
        HashMap<String, HiCoinOutputDTO> dataMap = new HashMap<>(16);
        for(HiCoinOutputDTO hiCoin: hiCoinOutputDTOList){
            dataMap.put(TimeUtils.getTime(hiCoin.getTargetDate().getTime(), TimeUtils.DATE_FORMAT_DATE_D), hiCoin);
        }
        for(int i = 0; i < dateList.size(); i++) {
            HiCoinOutputDTO hiCoinOutput = dataMap.get(dateList.get(i));
            if (hiCoinOutput != null) {
                data[0][i] = hiCoinOutput.getRechargePurchase();
                data[1][i] = hiCoinOutput.getActivityFund();
                data[2][i] = hiCoinOutput.getConsoleRelease();
                data[3][i] = hiCoinOutput.getOrderRefund();
                data[4][i] = hiCoinOutput.getOrderWalletPay();
            } else {
                for(int j = 0; j < name.length; j++)
                {
                    data[j][i] = 0L;
                }
            }
        }

        return generateResponse(name, data, dateList);
    }

    @Override
    public JSONArray diamondCommissionDetail(String channel, String startTime, String endTime) {
        Integer []changeId =  {100, 101, 102, 103, 108, 109, 110, 111, 112, 113, 114, 116, 117, 119, 120, 121,
                122, 123, 124, 125, 126, 127, 128};
        List<Integer> changeIdList = Arrays.asList(changeId);
        JSONArray diamondCommissions = new JSONArray();
        List<OutputCommissionStatistics> outputCommissionStatisticsList =
                outputMapper.commissionDetail("diamond", changeIdList, channel,startTime, endTime);
        boolean isFirst = true;
        DiamondCommissionDTO diamondCommission = new DiamondCommissionDTO();
        Date lastTargetDate=null;
        for(OutputCommissionStatistics commissionStatistics: outputCommissionStatisticsList){
            if (!commissionStatistics.getTargetDate().equals(lastTargetDate) && !isFirst){
                diamondCommissions.add(diamondCommission);
                diamondCommission = new DiamondCommissionDTO();
            }
            switch (commissionStatistics.getChangeId()){
                case 100:
                    diamondCommission.setVoiceRoomSend(commissionStatistics.getCommission());
                    break;
                case 101:
                    diamondCommission.setNotVoiceRoomSend(commissionStatistics.getCommission());
                    break;
                case 102:
                    diamondCommission.setVoiceRoomBarrage(commissionStatistics.getCommission());
                    break;
                case 103:
                    diamondCommission.setDiamondExchangeCoin(commissionStatistics.getCommission());
                    break;
                case 108:
                    diamondCommission.setHitEgg(commissionStatistics.getCommission());
                    break;
                case 109:
                    diamondCommission.setOpenGuard(commissionStatistics.getCommission());
                    break;
                case 110:
                    diamondCommission.setPurchaseProp(commissionStatistics.getCommission());
                    break;
                case 111:
                    diamondCommission.setOpenNoble(commissionStatistics.getCommission());
                    break;
                case 112:
                    diamondCommission.setAccompanyOrder(commissionStatistics.getCommission());
                    break;
                case 113:
                    diamondCommission.setBlindDatingDelay(commissionStatistics.getCommission());
                    break;
                case 114:
                    diamondCommission.setMagicBox(commissionStatistics.getCommission());
                    break;
                case 116:
                    diamondCommission.setSupremeEgg(commissionStatistics.getCommission());
                    break;
                case 117:
                    diamondCommission.setWishBottle(commissionStatistics.getCommission());
                    break;
                case 119:
                    diamondCommission.setBlowNianBeast(commissionStatistics.getCommission());
                    break;
                case 120:
                    diamondCommission.setPlantCost(commissionStatistics.getCommission());
                    break;
                case 121:
                    diamondCommission.setFarmCost(commissionStatistics.getCommission());
                    break;
                case 122:
                    diamondCommission.setBuyTicket(commissionStatistics.getCommission());
                    break;
                case 123:
                    diamondCommission.setStarTrekCost(commissionStatistics.getCommission());
                    break;
                case 124:
                    diamondCommission.setMuchangwuyuGamingCost(commissionStatistics.getCommission());
                    break;
                case 125:
                    diamondCommission.setMuchangwuyuExchangeCost(commissionStatistics.getCommission());
                    break;
                case 126:
                    diamondCommission.setTreasureHuntCost(commissionStatistics.getCommission());
                    break;
                case 127:
                    diamondCommission.setKittenFishingGamingCost(commissionStatistics.getCommission());
                    break;
                case 128:
                    diamondCommission.setFindMoleGamingCost(commissionStatistics.getCommission());
                    break;
                default:
                    break;
            }
            lastTargetDate = commissionStatistics.getTargetDate();
            diamondCommission.setTargetDate(lastTargetDate);
            isFirst = false;
        }

        if (!isFirst) {
            diamondCommissions.add(diamondCommission);
        }

        return diamondCommissions;
    }

    @Override
    public JSONObject diamondCommissionPercent(String channel, String startTime, String endTime) {
        JSONArray diamondCommissions = diamondCommissionDetail(channel, startTime, endTime);
        List<DiamondCommissionDTO> diamondCommissionDTOList =
                JSONObject.parseArray(diamondCommissions.toJSONString(), DiamondCommissionDTO.class);
        List<String> dateList= dateUtil.getnDayList(startTime, endTime);
        String[] name = {"语音房送礼", "非语音房送礼", "语音房弹幕", "钻石兑换金豆", "滴滴花费", "开守护", "通用道具购买",
                "开通贵族", "陪玩订单扣款", "相亲房延时", "哒哒花费", "至尊扭蛋", "许愿瓶", "炸年兽", "种树花费", "开心农场花费",
                "购买比赛门票", "星际迷航花费", "牧场玩法消耗饲料", "兑换礼物消耗饲料", "魔力寻宝花费", "小猫钓鱼玩法消耗水晶",
                "打地鼠玩法消耗锤子"};
        Long[][] data = new Long[name.length][dateList.size()];
        HashMap<String, DiamondCommissionDTO> dataMap = new HashMap<>(16);
        for(DiamondCommissionDTO diamondCommissionDTO: diamondCommissionDTOList){
            dataMap.put(TimeUtils.getTime(diamondCommissionDTO.getTargetDate().getTime(),
                    TimeUtils.DATE_FORMAT_DATE_D), diamondCommissionDTO);
        }
        for(int i=0;i<dateList.size(); i++){
            DiamondCommissionDTO diamondCommission = dataMap.get(dateList.get(i));
            if (diamondCommission != null) {
                data[0][i] = diamondCommission.getVoiceRoomSend();
                data[1][i] = diamondCommission.getNotVoiceRoomSend();
                data[2][i] = diamondCommission.getVoiceRoomBarrage();
                data[3][i] = diamondCommission.getDiamondExchangeCoin();
                data[4][i] = diamondCommission.getHitEgg();
                data[5][i] = diamondCommission.getOpenGuard();
                data[6][i] = diamondCommission.getPurchaseProp();
                data[7][i] = diamondCommission.getOpenNoble();
                data[8][i] = diamondCommission.getAccompanyOrder();
                data[9][i] = diamondCommission.getBlindDatingDelay();
                data[10][i] = diamondCommission.getMagicBox();
                data[11][i] = diamondCommission.getSupremeEgg();
                data[12][i] = diamondCommission.getWishBottle();
                data[13][i] = diamondCommission.getBlowNianBeast();
                data[14][i] = diamondCommission.getPlantCost();
                data[15][i] = diamondCommission.getFarmCost();
                data[16][i] = diamondCommission.getBuyTicket();
                data[17][i] = diamondCommission.getStarTrekCost();
                data[18][i] = diamondCommission.getMuchangwuyuGamingCost();
                data[19][i] = diamondCommission.getMuchangwuyuExchangeCost();
                data[20][i] = diamondCommission.getTreasureHuntCost();
                data[21][i] = diamondCommission.getKittenFishingGamingCost();
                data[22][i] = diamondCommission.getFindMoleGamingCost();
            }
            else{
                for(int j = 0; j < name.length; j++)
                {
                    data[j][i] = 0L;
                }
            }
        }

        return generateResponse(name, data, dateList);
    }

    @Override
    public JSONArray coinCommissionDetail(String channel, String startTime, String endTime) {
        Integer []changeId =  {100, 101, 105, 104, 106, 107};
        List<Integer> changeIdList = Arrays.asList(changeId);
        JSONArray coinCommissions = new JSONArray();
        List<OutputCommissionStatistics> outputCommissionStatisticsList =
                outputMapper.commissionDetail("coins", changeIdList, channel,startTime, endTime);
        boolean isFirst = true;
        CoinCommissionDTO coinCommission = new CoinCommissionDTO();
        Date lastTargetDate=null;
        for(OutputCommissionStatistics commissionStatistics: outputCommissionStatisticsList){
            if (!commissionStatistics.getTargetDate().equals(lastTargetDate) && !isFirst){
                coinCommissions.add(coinCommission);
                coinCommission = new CoinCommissionDTO();
            }
            switch (commissionStatistics.getChangeId()){
                case 100:
                    coinCommission.setVoiceRoomSend(commissionStatistics.getCommission());
                    break;
                case 101:
                    coinCommission.setNotVoiceRoomSend(commissionStatistics.getCommission());
                    break;
                case 105:
                    coinCommission.setAnswerQuestionCost(commissionStatistics.getCommission());
                    break;
                case 104:
                    coinCommission.setGuessSongCost(commissionStatistics.getCommission());
                    break;
                case 106:
                    coinCommission.setWerewolfKillCost(commissionStatistics.getCommission());
                    break;
                case 107:
                    coinCommission.setDrawAndGuessCost(commissionStatistics.getCommission());
                    break;
                default:
                    break;
            }
            lastTargetDate = commissionStatistics.getTargetDate();
            coinCommission.setTargetDate(lastTargetDate);
            isFirst = false;
        }

        if (!isFirst) {
            coinCommissions.add(coinCommission);
        }

        return coinCommissions;
    }

    @Override
    public JSONObject coinCommissionPercent(String channel, String startTime, String endTime) {
        JSONArray coinCommissions = coinCommissionDetail(channel, startTime, endTime);
        List<CoinCommissionDTO> coinCommissionDTOList = JSONObject.parseArray(coinCommissions.toJSONString(),
                CoinCommissionDTO.class);
        List<String> dateList= dateUtil.getnDayList(startTime, endTime);
        Long[][] data = new Long[7][dateList.size()];
        String []name = {"语音房送礼","非语音房送礼", "答题房费", "猜歌房费", "斗地主房费", "狼人杀房费", "你画我猜换词"};
        HashMap<String, CoinCommissionDTO> dataMap = new HashMap<>(16);
        for(CoinCommissionDTO coin: coinCommissionDTOList) {
            dataMap.put(TimeUtils.getTime(coin.getTargetDate().getTime(), TimeUtils.DATE_FORMAT_DATE_D), coin);
        }

        for(int i = 0; i < coinCommissions.size(); i++){
            CoinCommissionDTO coinCommission = dataMap.get(dateList.get(i));
            if (coinCommission != null) {
                data[0][i] = coinCommission.getVoiceRoomSend();
                data[1][i] = coinCommission.getNotVoiceRoomSend();
                data[2][i] = coinCommission.getAnswerQuestionCost();
                data[3][i] = coinCommission.getGuessSongCost();
                data[4][i] = coinCommission.getLandlordCost();
                data[5][i] = coinCommission.getWerewolfKillCost();
                data[6][i] = coinCommission.getDrawAndGuessCost();
            }
            else
            {
                for(int j = 0; j < name.length; j++)
                {
                    data[j][i] = 0L;
                }
            }
        }

        return generateResponse(name, data, dateList);
    }

    @Override
    public JSONArray hiCoinCommissionDetail(String channel, String startTime, String endTime) {
        Integer []changeId =  {5, 9, 112};
        List<Integer> changeIdList = Arrays.asList(changeId);
        JSONArray hiCoinCommissions = new JSONArray();
        List<OutputCommissionStatistics> outputCommissionStatisticsList =
                outputMapper.commissionDetail("hicoin", changeIdList, channel,startTime, endTime);
        boolean isFirst = true;
        HiCoinCommissionDTO hiCoinCommission = new HiCoinCommissionDTO();
        Date lastTargetDate=null;
        for(OutputCommissionStatistics commissionStatistics: outputCommissionStatisticsList){
            if (!commissionStatistics.getTargetDate().equals(lastTargetDate) && !isFirst){
                hiCoinCommissions.add(hiCoinCommission);
                hiCoinCommission = new HiCoinCommissionDTO();
            }
            switch (commissionStatistics.getChangeId()){
                case 5:
                    hiCoinCommission.setActivityFund(commissionStatistics.getCommission());
                    break;
                case 9:
                    hiCoinCommission.setConsoleDeduction(commissionStatistics.getCommission());
                    break;
                case 112:
                    hiCoinCommission.setOrderPay(commissionStatistics.getCommission());
                    break;
                default:
                    break;
            }
            lastTargetDate = commissionStatistics.getTargetDate();
            hiCoinCommission.setTargetDate(lastTargetDate);
            isFirst = false;
        }

        if (!isFirst) {
            hiCoinCommissions.add(hiCoinCommission);
        }

        return hiCoinCommissions;
    }

    @Override
    public JSONObject hiCoinCommissionPercent(String channel, String startTime, String endTime) {
        JSONArray hiCoinCommissions = hiCoinCommissionDetail(channel, startTime, endTime);
        List<HiCoinCommissionDTO> hiCoinCommissionDTOList = JSONObject.parseArray(
                hiCoinCommissions.toJSONString(), HiCoinCommissionDTO.class);
        List<String> dateList = dateUtil.getnDayList(startTime, endTime);
        Long[][] data = new Long[3][dateList.size()];
        String[] name = {"活动发放", "控制台扣除", "陪玩下单"};
        HashMap<String, HiCoinCommissionDTO> dataMap = new HashMap<>(16);
        for(HiCoinCommissionDTO hiCoin: hiCoinCommissionDTOList) {
            dataMap.put(TimeUtils.getTime(hiCoin.getTargetDate().getTime(), TimeUtils.DATE_FORMAT_DATE_D), hiCoin);
        }

        for(int i = 0; i < dateList.size(); i++) {
            HiCoinCommissionDTO hiCoinCommission = dataMap.get(dateList.get(i));
            if (hiCoinCommission != null) {
                data[0][i] = hiCoinCommission.getActivityFund();
                data[1][i] = hiCoinCommission.getConsoleDeduction();
                data[2][i] = hiCoinCommission.getOrderPay();
            }
            else
            {
                for(int j = 0; j < name.length; j++)
                {
                    data[j][i] = 0L;
                }
            }
        }

        return generateResponse(name, data, dateList);
    }

    private JSONObject generateResponse(String[] name, Long[][] data, List<String> dateList) {
        JSONArray dataList = new JSONArray();
        for(int i = 0; i < name.length; i++){
            JSONObject o = new JSONObject();
            o.put("name", name[i]);
            o.put("data", data[i]);
            dataList.add(o);
        }

        JSONObject response = new JSONObject();
        response.put("date", JSONArray.parseArray(JSON.toJSONString(dateList)));
        response.put("data", dataList);
        return response;
    }

    @Override
    public JSONObject getOutputConsumptionDetail(String uid, String channel, String startTime, String endTime, String orderBy, String orderType, String offset, String limit) {
        HashMap<String, String> orderByMap = new HashMap<String, String>() {
            {
                put("dtdate", "dtdate");
                put("payAll", "pay_all");
                put("payDiamond", "pay_diamond");
                put("payHicoin", "pay_hicoin");
                put("consumeDiamond", "consume_diamond");
                put("consumeHicoin", "consume_hicoin");
                put("giftDiamond", "gift_diamond");
            }
        };
        orderBy = orderByMap.get(orderBy);

        int count = outputConsumptionDetailMapper.getOutputConsumptionDetailCount(uid, channel, startTime, endTime);
        List<HashMap<String, Long>> total = outputConsumptionDetailMapper.getOutputConsumptionDetailTotal(uid, channel, startTime, endTime);
        List<OutputConsumptionDetail> items = outputConsumptionDetailMapper.getOutputConsumptionDetail(uid, channel, startTime, endTime, orderBy, orderType, Integer.parseInt(offset), Integer.parseInt(limit));

        JSONObject jsonObj = new JSONObject();
        jsonObj.put("count", count);
        jsonObj.put("items", items);
        for (HashMap<String, Long> item : total) {
            jsonObj.put("sum", item);
        }
        return jsonObj;
    }

    @Override
    public JSONObject getRechargeStatisticList(String channel, String subChannel, String startTime, String endTime, Integer offset, Integer limit) {
        int count = dailyRechargeDataDOMapper.getCount(channel, subChannel, startTime, endTime);
        List<DailyRechargeDataDO> items = dailyRechargeDataDOMapper.getList(channel, subChannel, startTime, endTime, offset, limit);
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("count", count);
        jsonObj.put("items", items);
        return jsonObj;
    }
}
